package com.etalk.crm.serviceImpl;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.etalk.crm.client.InvokingService;
import com.etalk.crm.dao.*;
import com.etalk.crm.pojo.*;
import com.etalk.crm.service.WorkflowService;
import com.etalk.crm.utils.DateUtil;
import com.etalk.crm.utils.OssGetObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

/**
 * @author Jordan
 */
@Service
public class WorkflowServiceImpl implements WorkflowService {
    private static final Logger logger = LogManager.getLogger(WorkflowServiceImpl.class);

    @Resource
    private WorkflowMapper workflowMapper;
    @Resource
    private LessonsMapper lessonsMapper;
    @Resource
    private KcOrdersMapper kcOrdersMapper;
    @Resource
    private OperationRecordMapper operationRecordMapper;
    @Resource
    private OrderLogMapper orderLogMapper;
    @Resource
    private InvokingService invokingService;
    @Resource
    private HttpSession session;

    /**
     * 查询工作流列表
     * @param record 查询条件
     * @param pageNum 页码
     * @param pageSize 每页记录
     * @return 列表数据
     */
    @Override
    public PageInfo<WorkflowResult> searchWorkflowPage(WorkflowResult record,int pageNum,int pageSize){
        PageHelper.startPage(pageNum, pageSize);

        if (record==null){
            record=new WorkflowResult();
        }
        record.setApprovalUserId(Integer.parseInt(session.getAttribute("userid").toString()));
        if (Integer.parseInt(session.getAttribute("storesId").toString())!=1 ){
            record.setCreatorId(Integer.parseInt(session.getAttribute("userid").toString()));
        }

        List<WorkflowResult> list=workflowMapper.selectWorkflowByPage(record);
        return new PageInfo<>(list);
    }

    /**
     * 查询工作流对应的问题类型
     * @return 数据流
     */
    @Override
    public List<Map<String,Object>> searchWorkflowQuestionTypeList(int processSettingId){
        return workflowMapper.selectWorkflowQuestionTypeList(processSettingId);
    }

    /**
     * 创建工作流数据初始化
     * @param lessonId 课程id
     * @return
     */
    @Override
    public Map<String,Object> searchInitWorkflow(int lessonId) {
        Map<String,Object> resultMap=new HashMap<String, Object> (3);
        //查询课程信息
        WorkflowCreate record=workflowMapper.selectClassInfoByLessonId(lessonId);
        resultMap.put("classInfo",record);
        resultMap.put("listType",workflowMapper.selectWorkflowTypeListByLessonId(lessonId));

        return resultMap;
    }

    /**
     * 查询工作流类型列表
     * @return
     */
    @Override
    public List<WorkflowResult> searchWorkflowList(){
        return workflowMapper.selectWorkflowTypeList();
    }
    @Override
    public Map<String,Object> searchInitEditWorkflow(int workflowId){
        Map<String,Object> resultMap=new HashMap<> (3);
        WorkflowCreate record=workflowMapper.selectWorkflowById(workflowId);
        if (!StringUtils.isEmpty(record.getFilePaths())){
            List<String> list=new ArrayList<>();
            for (String filePath : record.getFilePaths().split(",")) {
                list.add("//hnres.etalk365.com" + filePath);
            }
            record.setFilePaths(JSON.toJSONString(list));
        }
        resultMap.put("workflowInfo",record);

        //工作流类型
        resultMap.put("listType",workflowMapper.selectWorkflowTypeList());

        //工作流对应的问题类型
        resultMap.put("listQuestion",this.searchWorkflowQuestionTypeList(record.getProcessSettingId()));

        return resultMap;
    }

  /**
     * 审批数据初始化
     * @param workerId 工作流id
     * @return
     */
    @Override
    public Map<String,Object> searchViewApprovalInfo(long workerId){
        Map<String,Object> resultMap=new HashMap<String, Object> (3);
        List<WorkflowApprovalResult> listApproval=workflowMapper.selectApprovalInfo(workerId);
        resultMap.put("listApproval",listApproval);

        WorkflowCreate record=workflowMapper.selectWorkflowInfoByWorkflowId(workerId);
        if (!StringUtils.isEmpty(record.getFilePaths())){
            List<String> list=new ArrayList<>();
            for (String filePath : record.getFilePaths().split(",")) {
                list.add("//hnres.etalk365.com" + filePath);
            }
            record.setFilePaths(JSON.toJSONString(list));
        }
        resultMap.put("workflowInfo",record);
        return resultMap;
    }

    /**
     * 查询节点需要的操作
     * @param approvalId 流程id
     * @return
     */
    @Override
    public Map<String,Object> searchInitApprovalInfo(int approvalId){
        Map<String,Object> map=new HashMap<>(2);
        ProcessSettingsNode nodeInfo=workflowMapper.selectWorkflowApprovalNodeInfo(approvalId);
        map.put("nodeInfo",nodeInfo);

        if (nodeInfo!=null && nodeInfo.getReturnClass()==1 && nodeInfo.getIsReturn()==1) {
            map.put("listReason", lessonsMapper.selectReturnReasonList());
        }
        return map;
    }

    /**
     * 创建工作流
     * @param record 工作流信息
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int addWorkflow(WorkflowCreate record){
        record.setCreatorId(Integer.parseInt(session.getAttribute("userid").toString()));
        record.setCreator(session.getAttribute("loginname").toString());
        if (StringUtils.isEmpty(record.getCountingClass())){
            record.setCountingClass(1);
        }
        if (StringUtils.isEmpty(record.getReturnClass())){
            record.setReturnClass(0);
        }
        int num=workflowMapper.insertWorkflow(record);
        if (num>0){
            //保存附件到数据库
            if (record.getListFilePath()!=null && record.getListFilePath().size()>0) {
                workflowMapper.insertWorkflowFiles(record.getId(), record.getListFilePath());
            }
            //添加下一审批节点，如果没有下一节点，工作流结束
            Integer nodeId=workflowMapper.selectApprovalNextNode(record.getId());
            if (nodeId!=null){
                workflowMapper.insertWorkflowApprovalStatus(record.getId(),nodeId);
            }else {
                workflowMapper.updateWorkflowStateById(record.getId());
            }
        }
        return num;
    }

    /**
     * 修改工作流
     * @param record 修改后的信息
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int editWorkflow(WorkflowCreate record){
        if (StringUtils.isEmpty(record.getReturnClass())){
            record.setReturnClass(0);
        }
        if (StringUtils.isEmpty(record.getCountingClass())){
            record.setCountingClass(1);
        }
        int num=workflowMapper.updateWorkflow(record);
        if (num>0) {
            //保存附件到数据库
            if (record.getListFilePath() != null && record.getListFilePath().size() > 0) {
                if (workflowMapper.deleteWorkflowFiles(record.getId())>0 && !StringUtils.isEmpty(record.getFilePaths())){
                    for (String filepath:record.getFilePaths().split(",")) {
                        OssGetObject.deleteActivityInfoAttachment(filepath);
                    }
                }
                workflowMapper.insertWorkflowFiles(record.getId(), record.getListFilePath());
            }
            //已撤回的工作流修改后自动重启审批
            if(workflowMapper.selectPendingApprovalByWorkflowId(record.getId())==0) {
                //添加下一审批节点，如果没有下一节点，工作流结束
                Integer nodeId = workflowMapper.selectApprovalNextNode(record.getId());
                if (nodeId != null) {
                    workflowMapper.insertWorkflowApprovalStatus(record.getId(), nodeId);
                    //重启工作流
                    workflowMapper.updateWorkflowStateByResume(record.getId());
                } else {
                    workflowMapper.updateWorkflowStateById(record.getId());
                }
            }
        }
        return num;
    }

    /**
     * 撤回工作流
     * @param workflowId 工作流id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int revokeWorkflow(long workflowId){
        int num=workflowMapper.updateWorkflowStateByRevoke(workflowId);
        if (num>0) {
            workflowMapper.deleteWorkflowApprovalStatusByWorkflowId(workflowId);
        }
        return num;
    }

    /**
     * 审批工作流
     * @param record 工作流审批信息
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int addApproval(WorkflowApproval record){
        record.setUserId(Integer.parseInt(session.getAttribute("userid").toString()));
        if (!StringUtils.isEmpty(record.getReturnReasonId())){
            record.setReturnReasonIds(new ArrayList<>(1));
            record.getReturnReasonIds().add(record.getReturnReasonId());
        }
        if (StringUtils.isEmpty(record.getResultsId())){
            record.setResultsId(0);
        }
        if (StringUtils.isEmpty(record.getReturnClass())){
            record.setReturnClass(0);
        }
        if (StringUtils.isEmpty(record.getCancelClass())){
            record.setCancelClass(1);
        }
        int num=workflowMapper.insertWorkflowApprovalResult(record);
        if (num>0) {
            if (record.getListFilePath()!=null && record.getListFilePath().size()>0) {
                //添加审批附件
                num = workflowMapper.insertWorkflowApprovalResultFiles(record.getId(), record.getListFilePath());
            }
            num = workflowMapper.updateWorkflowApprovalStatus(record.getApprovalStatusId(), record.getVersion(), 1, record.getUserId());

            if (num > 0) {
                //审批人同意
                if (record.getApprovalState()==1) {
                    //添加下一审批节点
                    Integer nodeId = workflowMapper.selectApprovalNextNode(record.getWorkflowId());
                    if (nodeId != null) {
                        workflowMapper.insertWorkflowApprovalStatus(record.getWorkflowId(), nodeId);
                    } else {
                        //没有下一个审批则工作流审批结束
                        workflowMapper.updateWorkflowStateById(record.getWorkflowId());
                    }
                    //不计算老师课时
                    if (record.getCancelClass()!=null && record.getCancelClass()==0){
                        //工作流中标记课程不算老师课时
                        workflowMapper.updateWorkflowCountingClassByWorkflowId(record.getWorkflowId());
                    }
                    //审批同意返还课时
                    if (record.getReturnClass()!=null && record.getReturnClass()==1) {
                        WorkflowCreate result = workflowMapper.selectWorkflowById(record.getWorkflowId());
                        if (result.getReturnClass()==1){
                            //查询课程信息
                            LessonResult lessonResult = lessonsMapper.selectLessonReturnInfoByLessonId(result.getLessonId());
                            //返还订单课时
                            kcOrdersMapper.updateLearnedClassSubByOrderId(lessonResult.getOrderId(),lessonResult.getPayMoney());
                            //标记课程已返还课时
                            lessonsMapper.updateLessonReturnByLessonId(result.getLessonId(),0);

                            KcOrders kcOrders=kcOrdersMapper.selectByOrderId(lessonResult.getOrderId());
                            String moneyType=kcOrders.getClassifyLevel() > 0 ? "E币" : "课时";
                            String newMoney=kcOrders.getClassifyLevel() > 0 ? String.format("%.2f", kcOrders.getLearnedClass() / (double) 100) : String.valueOf(kcOrders.getLearnedClass());;
                            //返还课时表加记录kcorder_consumption_record
                            Map<String, Object> recordMap = new HashMap<>(8);
                            recordMap.put("type", 3);
                            recordMap.put("payMoney", lessonResult.getPayMoney());
                            recordMap.put("surplusMoney", newMoney);
                            recordMap.put("personId", lessonResult.getPersonId());
                            recordMap.put("lessonId", result.getLessonId());
                            recordMap.put("orderId", lessonResult.getOrderId());
                            recordMap.put("remark", "返还课程成功，返还订单(" + lessonResult.getOrderId() + ")" + moneyType + lessonResult.getPayMoney() + "成功");
                            recordMap.put("creator", session.getAttribute("loginname").toString());
                            orderLogMapper.addConsumptionRecord(recordMap);

                            // 返还课时记录日志
                            OrderLog orderLog = new OrderLog();
                            orderLog.setOrderId(lessonResult.getOrderId());
                            orderLog.setPersonId(lessonResult.getPersonId());
                            orderLog.setRecorder(session.getAttribute("loginname").toString());
                            orderLog.setRecordTime(new Date());
                            orderLog.setState(OrderLogTypeEnum.RETURN_LESSON.getValue());
                            String returnReason = lessonsMapper.selectReturnReasonListByIds(record.getReturnReasonIds());
                            orderLog.setDesc("返还了课程" + result.getLessonId() + "(" + DateUtil.format(lessonResult.getReleaseTime(),"yyyy-MM-dd HH:mm:ss") + ")的消耗" + (moneyType + "(" + lessonResult.getPayMoney() + ")，已使用数量" + newMoney) + ",返还课时原因:" + returnReason);
                            orderLogMapper.addOrderLog(orderLog);

                            // 如果选择了原因
                            if (!CollectionUtils.isEmpty(record.getReturnReasonIds())) {
                                Map<String, Object> paramMap = new HashMap<>(3);
                                try {
                                    // 添加返还课时原因
                                    paramMap.put("lessonId", result.getLessonId());
                                    paramMap.put("returnReasonIds", record.getReturnReasonIds());
                                    paramMap.put("result", "");
                                    paramMap.put("creator", session.getAttribute("loginname").toString());
                                    lessonsMapper.insertReturnReason(paramMap);
                                }catch (Exception e) {
                                    if(e instanceof DuplicateKeyException){
                                        logger.warn(result.getLessonId()+"已经存在，无需重复插入，参数："+JSON.toJSONString(paramMap));
                                        logger.warn(e.getMessage());
                                    }else{
                                        logger.error(e.getMessage(),e);
                                        throw e;
                                    }
                                }
                            }

                            //添加课程操作记录
                            OperationRecord operationRecord = new OperationRecord();
                            operationRecord.setStudentName(lessonResult.getStudentLogin());
                            operationRecord.setUpdateName(session.getAttribute("loginname").toString());
                            operationRecord.setUpdateTime(new Date());
                            if (lessonResult.getState() == 2) {
                                operationRecord.setContent("返还学生" + lessonResult.getStudentLogin() + " 的已完成的课程(" + DateUtil.format(lessonResult.getReleaseTime(), "yyyy-MM-dd HH:mm:ss") + ")，并返还" + (kcOrders.getClassifyLevel() > 0 ? lessonResult.getPayMoney() : 1) + (kcOrders.getClassifyLevel() > 0 ? "E币" : "课时，该课仍扣除老师工资"));
                                //logger.info(session.get("loginname") + " 进入课程管理,取消学生" + less.getStudentLogin() + " 的已完成的课程(" + DateUtil.format(less.getReleaseTime(), "yyyy-MM-dd HH:mm:ss") + ")，并返还" + (less.getKcOrders().getClassifyLevel() > 0 ? less.getPayMoney() : 1) + (less.getKcOrders().getClassifyLevel() > 0 ? "E币" : "课时，该课仍扣除老师工资"));
                            } else if (lessonResult.getState() == 3) {
                                operationRecord.setContent("返还学生" + lessonResult.getStudentLogin() + " 的已旷课的课程(" + DateUtil.format(lessonResult.getReleaseTime(), "yyyy-MM-dd HH:mm:ss") + ")，并返还" + (kcOrders.getClassifyLevel() > 0 ? lessonResult.getPayMoney() : 1) + (kcOrders.getClassifyLevel() > 0 ? "E币" : "课时，该课不扣除老师工资"));
                                //logger.info("返还学生" + less.getStudentLogin() + " 的已旷课的课程(" + DateUtil.format(less.getReleaseTime(), "yyyy-MM-dd HH:mm:ss") + ")，并返还" + (less.getKcOrders().getClassifyLevel() > 0 ? less.getPayMoney() : 1) + (less.getKcOrders().getClassifyLevel() > 0 ? "E币" : "课时，该课不扣除老师工资"));
                            }else {
                                operationRecord.setContent("返还学生" + lessonResult.getStudentLogin() + " 的课程(" + DateUtil.format(lessonResult.getReleaseTime(), "yyyy-MM-dd HH:mm:ss") + ")，并返还" + (kcOrders.getClassifyLevel() > 0 ? lessonResult.getPayMoney() : 1) + (kcOrders.getClassifyLevel() > 0 ? "E币" : "课时"));
                            }
                            operationRecordMapper.insertOperationRecord(operationRecord);

                            //返还课时成功发送钉钉提醒
                            String msg="工作流（ID："+record.getWorkflowId()+"，学生：" + lessonResult.getStudentLogin() + "，课程：" + DateUtil.format(lessonResult.getReleaseTime(), "yyyy-MM-dd HH:mm") + "）申请返还课时已同意返还 " + (kcOrders.getClassifyLevel() > 0 ? lessonResult.getPayMoney() : 1) + (kcOrders.getClassifyLevel() > 0 ? " E币" : "课时");
                            invokingService.workflowFinishNotice(msg);
                        }
                    }
                }else if (record.getApprovalState()==0) {
                    //审批人拒绝，则结束工作流
                    workflowMapper.updateWorkflowStateById(record.getWorkflowId());
                    return num;
                }
            }

        }
        return num;
    }
}
